console.log(`
【fs 模块概述】
    Node.js 的文件系统模块 (fs) 允许我们与文件系统进行交互，
    提供了大量用于文件和目录操作的方法。这些方法通常有同步和异步两种版本。
  `);

console.log(`
【文件读取Api】
    1. fs.readFile()             异步读取
    2. fs.readFileSync()         同步读取
    3. fs.createReadStream()     流式读取
`);

console.log(
  `使用文件写入Api前，需要先导入fs模块：
   导入模块、require 是 Node.js 环境中的'全局'变量，用来导入模块
   const fs = require("fs");
  `
);
const fs = require("fs");

/**
 *  1、异步读取 readFile()
 *     使用 readFile异步读取 获取的是一个Buffer字节码格式的数据、是十六进制的编码格式
 *     如果转换为utf8的格式，可以通过 data.toStrong() 转换成字符串、或者通过配置项设定输出的格式
 */
console.log(`
【异步读取】: fs.readFile()
    功能：
        异步读取文件内容
    语法：
        fs.readFile(path, options, callback)
    参数：
        path 要读取的文件路径（必填）
        options 配置项（可选）
        callback 回调函数（必填）
            err 错误对象
            data 读取到的数据
    返回值：
        无
`);
const readFileUrl = "./01_文件写入.js";
const readFileOptions = {
  encoding: "utf8",
  flag: "r",
  mode: 0o666,
  autoClose: true,
  start: 0,
  end: 10,
  highWaterMark: 5,
  pos: 0,
};
fs.readFile(readFileUrl, readFileOptions, (err, data) => {
  if (err) {
    console.log("读取失败");
    return;
  }
  console.log(data);
});

console.log(`
【同步读取 readFileSync()】
    功能：
        同步读取文件内容
    语法：
        fs.readFileSync(path, options)
    参数：
        path 要读取的文件路径
        options 配置项
    返回值：
        读取到的文件内容
`);
const readFileSyncUrl = "./01_文件写入.js";
try {
  let file = fs.readFileSync(readFileSyncUrl);
  console.log(file);
  console.log(file.toString());
} catch (e) {
  console.log(e);
}

console.log(`
【流式读取】: fs.createReadStream()
    功能：
        流式读取文件内容
    语法：
        fs.createReadStream(path, options)
    参数：
        path 要读取的文件路径
        options 配置项
    返回值：
        读取到的文件内容
`);
const readStreamUrl = "./01_文件写入.js";
const readStreamOptions = {
  encoding: "utf8",
  flag: "r",
  mode: 0o666,
  autoClose: true,
  start: 0,
  end: 10,
  highWaterMark: 5,
  pos: 0,
};
let readStream = fs.createReadStream(readStreamUrl, readStreamOptions);
readStream.on("data", (data) => console.log(data.toString()));
readStream.on("end", () => console.log("读取完成"));
readStream.on("error", (err) => console.log(err.toString()));




console.log(`
【Promise版本的文件读取】
    功能：
        异步读取文件内容
    语法：
        fs.promises.readFile(path, options)
    参数：
        path 要读取的文件路径
        options 配置项
    返回值：
        读取到的文件内容
    特点：
        基于Promise，支持现代JavaScript异步编程模式
        可以与async/await结合使用，代码更简洁易读
        避免回调地狱
        支持try/catch错误处理
`);
fs.promises
  .readFile(readFileUrl, readFileOptions)
  .then((data) => console.log(data.toString()))
  .catch((err) => console.log(err.toString()));




  console.log(`
【options配置项详解】
    功能：
        配置文件写入的选项
    参数：
        1. flag 写入方式：
          - a+ 表示追加写入
          - w 表示写入
          - w+ 表示写入并读取
          - a 表示追加写入
          - r 表示读取
          - r+ 表示读取并写入
        2. encoding 字符编码
          - utf8 编码
          - base64 编码
          - binary 二进制编码
          - null 无编码
          - base64url 编码
          - ascii 7位编码
          - utf16le 16位小端编码
          - ucs2 16位编码
          - base64 编码
        3. mode 文件权限:
          - 0o666 读写权限
          - 0o644 只读权限
          - 0o755 读写执行权限
          - 0o744 只读执行权限
          - 0o733 读写执行权限
          - 0o722 读写执行权限
          - 0o711 读写执行权限
          - 0o700 只读执行权限
        4. fd 文件描述符:
          - 0 标准输入
          - 1 标准输出
          - 2 标准错误
        5. start 开始写入的位置
        6. end 结束写入的位置
        7. highWaterMark 每次写入的字节数
        8. pos 写入的位置、从文件的第几个字节开始写入
        9. atomic 原子写入
        10. signal 信号量、信号量是一个计数器，用于控制对共享资源的访问。
  `);


  console.log(`
  【文件读取方法比较】
        1. 异步读取(readFile)：适合小文件读取，不会阻塞主线程
          - 优点：不阻塞主线程
          - 缺点：一次性将文件内容加载到内存，不适合大文件
          - 适用场景：读取配置文件、小型数据文件

        2. 同步读取(readFileSync)：适合简单脚本或初始化操作
          - 优点：代码简洁，直接返回结果
          - 缺点：阻塞主线程
          - 适用场景：启动时读取配置、工具脚本

        3. 流式读取(createReadStream)：适合大文件读取
          - 优点：分块读取，内存占用小
          - 缺点：代码相对复杂，需要处理事件
          - 适用场景：读取日志文件、视频文件等大文件
    `);
  


console.log(`
【Buffer数据处理】
        - 当不指定encoding选项时，readFile和readFileSync返回的是Buffer对象
        - Buffer是Node.js中用于处理二进制数据的类
        - 可以通过toString()方法将Buffer转换为字符串
        - 也可以通过Buffer.from()创建Buffer对象
  `);



console.log(`
【错误处理】
        - 异步读取：通过回调函数的err参数处理错误
        - 同步读取：使用try-catch捕获异常
        - 流式读取：通过监听'error'事件处理错误
  `);



